Dynomotion

Group: DynoMotion Message: 12143 From: Hardy Family Date: 8/23/2015
Subject: Writing 2nd half flash
Hi Tom,

I tried running your sample programs WriteData.c and ReadSavedData.c, and they work, however I cannot work out how to write to pages of flash beyond the 0th one.

Here's the sample code for reference:

#include "KMotionDef.h"
 
#define FLASH ((volatile char *)0x90000000)
void ProgramFlash(volatile char *src, int Length, volatile char *dest, char *message);
 
main()
{
    // put some data in a buffer that we want to save
    gather_buffer[0]=99999.4;
    gather_buffer[1]=444.1;
    gather_buffer[2]=-1.0;
     
    // write 256 bytes of the buffer to the 2nd MByte of the Flash Chip
    ProgramFlash((volatile char *)gather_buffer,256,FLASH+0x100000,""); 
}


and...

#include "KMotionDef.h"
 
#define FLASH ((volatile char *)0x90000000)
void SetFlashBank(volatile unsigned short *add);
 
main()
{
    double *p=(double*)FLASH;  // pointer to the FLASH Chip
         
    SetFlashBank(p); // the DSP external bus is banked, this routine selects the bank for the address 
     
    printf("Saved 0 1 2 = %f %f %f\n",p[0],p[1],p[2]);  // now we can access the data 
}


Could you please give some more details on what SetFlashBank does?

What I don't understand is the addressing differences: in ProgramFlash(), you don't set the bank and pass the base address (0x9000000) plus 1M, but when reading you use the same base address without adding the 1M.

I tried adding 64k to each address to get to the next 64k page, but I can't tell whether it is the write or read which fails.

Also, SetFlashBank() is declared as taking a pointer to short - any reason for that?

Is there any significance to the "msg" parameter of ProgramFlash()?

Regards,
SJH

Group: DynoMotion Message: 12145 From: Tom Kerekes Date: 8/25/2015
Subject: Re: Writing 2nd half flash
Attachments :
    Hi SJH,

    You are correct the ReadFlashData.c example has a bug.  The 1MByte offset isn't added in when setting the FlashBank (or referencing the data address).  It works because the SetFlashBank has a protection feature preventing access to the beginning of Flash which is the primary boot sector region.  When attempting to set the FlashBank to that Block it is ignored and set to the beginning of the 2nd Meg of Flash instead.

    See attached two block example.

    Regarding your questions:

    SetFlashBank sets the upper bits of any flash address (address bits 14 through 19) - but doesn't allow setting to first block.

    The Flash chip is a 16-bit device hence the address and writes are performed as 16 bit writes.

    In addition we found a bug in the ProgramFlash routine.  Its difficult to explain but it is basically programming double the number of data as specified.  But then check summing the total amount programmed with half of the input data used.  This works if the extra data specified is all zero.  The result of all this is that the entire 2 MBytes of Flash is currently being programmed with the 2nd MByte all zeros (unlike what we told you earlier).  We intend to fix all this but may take some time.

    We have also found the Reboot! command to still be unreliable.

    Please give us some time to look into all these issues.

    Regards
    TK





    Group: DynoMotion Message: 12148 From: Hardy Family Date: 8/25/2015
    Subject: Re: Writing 2nd half flash
    Thanks for the progress report.  No great urgency, since we are probably a few weeks out from release.  Look forward to getting new firmware (since it helps us test our "easy firmware update" procedure).

    Regards,
    SJH


    On Tue, Aug 25, 2015 at 10:26 AM, Tom Kerekes tk@... [DynoMotion] <DynoMotion@yahoogroups.com> wrote:
     

    Hi SJH,

    You are correct the ReadFlashData.c example has a bug.  The 1MByte offset isn't added in when setting the FlashBank (or referencing the data address).  It works because the SetFlashBank has a protection feature preventing access to the beginning of Flash which is the primary boot sector region.  When attempting to set the FlashBank to that Block it is ignored and set to the beginning of the 2nd Meg of Flash instead.

    See attached two block example.

    Regarding your questions:

    SetFlashBank sets the upper bits of any flash address (address bits 14 through 19) - but doesn't allow setting to first block.

    The Flash chip is a 16-bit device hence the address and writes are performed as 16 bit writes.

    In addition we found a bug in the ProgramFlash routine.  Its difficult to explain but it is basically programming double the number of data as specified.  But then check summing the total amount programmed with half of the input data used.  This works if the extra data specified is all zero.  The result of all this is that the entire 2 MBytes of Flash is currently being programmed with the 2nd MByte all zeros (unlike what we told you earlier).  We intend to fix all this but may take some time.

    We have also found the Reboot! command to still be unreliable.

    Please give us some time to look into all these issues.

    Regards
    TK





    Group: DynoMotion Message: 12181 From: Tom Kerekes Date: 8/29/2015
    Subject: Re: Writing 2nd half flash
    Hi SJH,

    Here is a test Version 4.33q where the Reboot! command should work reliably (problem turned out to be a cache coherency issue after re-loading code).  Please note that the Reboot! Fix is part of the KFLOP Firmware. This means the Reboot! command in your existing Firmware is still not functional.  After flashing this new Firmware you will still need one more Power Cycle (or Hardware Reset) to boot into the new Firmware. Thereafter the Reboot! command should be functional. 

    This version contains new and updated Versions of the non-volatile functions.

    There is also a new capability to have KFLOP read from a PC Disk file.



    Please inform us of any issues.

    Regards
    TK


    Group: DynoMotion Message: 13530 From: gyelle10 Date: 7/11/2016
    Subject: Re: Writing 2nd half flash
    Hi,

    I'm trying save the CoordMotionBuffer in the 2nd half of flash memory at specific adresses. I keep track of the number of adresses that each project needs and I want to save multiple project in Flash. So when I want to save project 2, I have to save the CoordMotionBuffer at 0x90100000 + an offset. The offset is the number of adresses needed by the 1st project. I obtain the number of adresses needed by each project when I execute them and then by :
     int QoA_project = (ParametricIndex+1)*sizeof(ParametricCoeffs[0]); //Quantity of adresses.

     My question is, how do I write to this offset ? 
    I don't understand what kind of parameter do I have to add to FLASH_USER in the ProgramFlash() fonction.


    #define FLASH_USER ((volatile char *)0x90100000)  // 2nd MegByte is for User use

    ProgramFlash((volatile char *)ParametricCoeffs,QoA_project/sizeof(short int),FLASH_USER+offset,""); 

    I have the offset computed as a double in decimal... 

    Thanks in advance,


    Guillaume
     
    Group: DynoMotion Message: 13532 From: Tom Kerekes Date: 7/11/2016
    Subject: Re: Writing 2nd half flash

    Hi Guillaume,

    Your QoA_project value is in units of bytes the same as FLASH_USER so you should be able to simply add them together.

    However the Flash Chip works in 64K byte blocks. 16 blocks = 1 MByte.  To write even 1 word to the Flash Chip the ProgramFlash first erases the entire 64K byte block.  So it would be simplest to round the destination address up to the next 64K byte boundary.  I believe this code will do this:

     QoA_project = (QoA_project+0xffff)&(~0xffff);

    If you do not want to waste space by ounding up to the next 64KByte boundary for each project then you will need to save all the projects into temporary memory (the 8MByte gather buffer) and then Flash it all at once into the Flash Chip by calling ProgramFlash only one time.

    HTH

    Regards

    TK



    On 7/11/2016 9:56 AM, gyelle10@... [DynoMotion] wrote:
     

    Hi,


    I'm trying save the CoordMotionBuffer in the 2nd half of flash memory at specific adresses. I keep track of the number of adresses that each project needs and I want to save multiple project in Flash. So when I want to save project 2, I have to save the CoordMotionBuffer at 0x90100000 + an offset. The offset is the number of adresses needed by the 1st project. I obtain the number of adresses needed by each project when I execute them and then by :
     int QoA_project = (ParametricIndex+1)*sizeof(ParametricCoeffs[0]); //Quantity of adresses.

     My question is, how do I write to this offset ? 
    I don't understand what kind of parameter do I have to add to FLASH_USER in the ProgramFlash() fonction.


    #define FLASH_USER ((volatile char *)0x90100000)  // 2nd MegByte is for User use

    ProgramFlash((volatile char *)ParametricCoeffs,QoA_project/sizeof(short int),FLASH_USER+offset,""); 

    I have the offset computed as a double in decimal... 

    Thanks in advance,


    Guillaume
     

    Group: DynoMotion Message: 13535 From: gyelle10 Date: 7/12/2016
    Subject: Re: Writing 2nd half flash
    Hi Tom,

    I can't waste the space, so I'll do the second option but I can't find many information concerning gather_buffer..

    How do I copy all flash memory into gather ? How can I specify that the kind of variable that I want to put are PARAMETRIC_COEFF ?

    Here is my program :


    //COPY ALL FLASHED PROJECT IN GATHER
    PARAMETRIC_COEFF *p=(PARAMETRIC_COEFF*)FLASHC;  // pointer to the FLASH Chip
    SetFlashBank(FLASHC); // the DSP external bus is banked, this routine selects the bank for the address 
    // now we can access the data 
    int i;
    T2=Time_sec();
    for(i=0; i<=offset; i++) //    offset is the sum of QoA_project of every previous project
    {
    gather_buffer[i]=p[i];
    }
    T3=Time_sec();
    printf ("Flash to gather Complete,time = %fs offset = %d \n",T2-T3,offset);


    Then I want to add my current project which is in the CoordMotionBuffer to the Gather_Buffer

    // ADD CURRENT PROJECT TO GATHER_BUFFER
    int j;
    for(j=0; j<=QoA_project]; j++) // QoA_project contains the number of bytes of the current project
    {
    gather_buffer[j+offset+1]=ParametricCoeffs[j];
    }


     Finally I copy the gather_buffer in flash 

    // COPY GATHER_BUFFER INTO FLASH
    T0=Time_sec();
    // write QoA_project1 bytes of the CoordMotionBuffer to the 2nd MByte of the Flash Chip
    ProgramFlash((volatile char *)ParametricCoeffs,(offset+QoA_project)/sizeof(short int),FLASH_USER,""); 
    T1=Time_sec();
    printf ("Operation Complete,time = %fs for %d bytes remaining\n",T1-T0,1000000-offset-QoA_project);
    }

    I attached the whole program,

    Thanks in advance


    Guillaume






    On Monday, July 11, 2016 7:03 PM, "Tom Kerekes tk@... [DynoMotion]" <DynoMotion@yahoogroups.com> wrote:


     
    Hi Guillaume,
    Your QoA_project value is in units of bytes the same as FLASH_USER so you should be able to simply add them together.
    However the Flash Chip works in 64K byte blocks. 16 blocks = 1 MByte.  To write even 1 word to the Flash Chip the ProgramFlash first erases the entire 64K byte block.  So it would be simplest to round the destination address up to the next 64K byte boundary.  I believe this code will do this:
     QoA_project = (QoA_project+0xffff)&(~0xffff);
    If you do not want to waste space by ounding up to the next 64KByte boundary for each project then you will need to save all the projects into temporary memory (the 8MByte gather buffer) and then Flash it all at once into the Flash Chip by calling ProgramFlash only one time.
    HTH
    Regards
    TK


    On 7/11/2016 9:56 AM, gyelle10@... [DynoMotion] wrote:
     
    Hi,

    I'm trying save the CoordMotionBuffer in the 2nd half of flash memory at specific adresses. I keep track of the number of adresses that each project needs and I want to save multiple project in Flash. So when I want to save project 2, I have to save the CoordMotionBuffer at 0x90100000 + an offset. The offset is the number of adresses needed by the 1st project. I obtain the number of adresses needed by each project when I execute them and then by :
     int QoA_project = (ParametricIndex+1)*sizeof(ParametricCoeffs[0]); //Quantity of adresses.

     My question is, how do I write to this offset ? 
    I don't understand what kind of parameter do I have to add to FLASH_USER in the ProgramFlash() fonction.


    #define FLASH_USER ((volatile char *)0x90100000)  // 2nd MegByte is for User use

    ProgramFlash((volatile char *)ParametricCoeffs,QoA_project/sizeof(short int),FLASH_USER+offset,""); 

    I have the offset computed as a double in decimal... 

    Thanks in advance,


    Guillaume
     



      @@attachment@@
    Group: DynoMotion Message: 13538 From: Tom Kerekes Date: 7/12/2016
    Subject: Re: Writing 2nd half flash [1 Attachment]

    Hi Guillaume,

    Please read up about C Pointers.  You are missing some basic concepts.  In C Pointers point to memory byte addresses of objects of a certain type/size.  For example gather_buffer is defined as a pointer to doubles (which are 8 byte objects).  You are defining "p" as a pointer to a PARAMETRIC_COEFF which is a pointer to an object like 216bytes in size.   You can't write an object of one size to a memory space of an object of a different size.  So:

    gather_buffer[i]=p[i];

    is not proper.  The simplest thing would be to cast pointers to type char (bytes):

    char *p=(char *)FLASH_USER;  // pointer to the User FLASH Chip area.


    HTH
    Regards
    TK




    On 7/12/2016 8:53 AM, gyelle10@... [DynoMotion] wrote:
     
    Hi Tom,

    I can't waste the space, so I'll do the second option but I can't find many information concerning gather_buffer..

    How do I copy all flash memory into gather ? How can I specify that the kind of variable that I want to put are PARAMETRIC_COEFF ?

    Here is my program :


    //COPY ALL FLASHED PROJECT IN GATHER
    PARAMETRIC_COEFF *p=(PARAMETRIC_COEFF*)FLASHC;  // pointer to the FLASH Chip
    SetFlashBank(FLASHC); // the DSP external bus is banked, this routine selects the bank for the address 
    // now we can access the data 
    int i;
    T2=Time_sec();
    for(i=0; i<=offset; i++) //    offset is the sum of QoA_project of every previous project
    {
    gather_buffer[i]=p[i];
    }
    T3=Time_sec();
    printf ("Flash to gather Complete,time = %fs offset = %d \n",T2-T3,offset);


    Then I want to add my current project which is in the CoordMotionBuffer to the Gather_Buffer

    // ADD CURRENT PROJECT TO GATHER_BUFFER
    int j;
    for(j=0; j<=QoA_project]; j++) // QoA_project contains the number of bytes of the current project
    {
    gather_buffer[j+offset+1]=ParametricCoeffs[j];
    }


     Finally I copy the gather_buffer in flash 

    // COPY GATHER_BUFFER INTO FLASH
    T0=Time_sec();
    // write QoA_project1 bytes of the CoordMotionBuffer to the 2nd MByte of the Flash Chip
    ProgramFlash((volatile char *)ParametricCoeffs,(offset+QoA_project)/sizeof(short int),FLASH_USER,""); 
    T1=Time_sec();
    printf ("Operation Complete,time = %fs for %d bytes remaining\n",T1-T0,1000000-offset-QoA_project);
    }

    I attached the whole program,

    Thanks in advance


    Guillaume






    On Monday, July 11, 2016 7:03 PM, "Tom Kerekes tk@... [DynoMotion]" <DynoMotion@yahoogroups.com> wrote:


     
    Hi Guillaume,
    Your QoA_project value is in units of bytes the same as FLASH_USER so you should be able to simply add them together.
    However the Flash Chip works in 64K byte blocks. 16 blocks = 1 MByte.  To write even 1 word to the Flash Chip the ProgramFlash first erases the entire 64K byte block.  So it would be simplest to round the destination address up to the next 64K byte boundary.  I believe this code will do this:
     QoA_project = (QoA_project+0xffff)&(~0xffff);
    If you do not want to waste space by ounding up to the next 64KByte boundary for each project then you will need to save all the projects into temporary memory (the 8MByte gather buffer) and then Flash it all at once into the Flash Chip by calling ProgramFlash only one time.
    HTH
    Regards
    TK


    On 7/11/2016 9:56 AM, gyelle10@... [DynoMotion] wrote:
     
    Hi,

    I'm trying save the CoordMotionBuffer in the 2nd half of flash memory at specific adresses. I keep track of the number of adresses that each project needs and I want to save multiple project in Flash. So when I want to save project 2, I have to save the CoordMotionBuffer at 0x90100000 + an offset. The offset is the number of adresses needed by the 1st project. I obtain the number of adresses needed by each project when I execute them and then by :
     int QoA_project = (ParametricIndex+1)*sizeof(ParametricCoeffs[0]); //Quantity of adresses.

     My question is, how do I write to this offset ? 
    I don't understand what kind of parameter do I have to add to FLASH_USER in the ProgramFlash() fonction.


    #define FLASH_USER ((volatile char *)0x90100000)  // 2nd MegByte is for User use

    ProgramFlash((volatile char *)ParametricCoeffs,QoA_project/sizeof(short int),FLASH_USER+offset,""); 

    I have the offset computed as a double in decimal... 

    Thanks in advance,


    Guillaume
     




    Group: DynoMotion Message: 13546 From: Hardy Family Date: 7/12/2016
    Subject: Re: Writing 2nd half flash
    Check out the bottom of
    http://dynomotion.com/Support.html
    for a list of resources for help programming C.

    Note that the memcpy() function is available (even though it may not be listed in KMotionDef.h).  memcpy() copies bytes from one location to another, without regard for the type of pointed-to objects.  For example:

    extern void * memcpy(void * dest, const void * source, unsigned int number_of_bytes);  // external definition

    (in C, void* means "pointer to an unspecified object" so you can use any pointer as a parameter in this case.)

    Then, if you want to copy from flash to the gather buffer:

    memcpy(gather_buffer, FLASH_USER, sizeof(PARAMETRIC_COEFF) * number_of_parametric_coeffs);

    where as you can see, you calculate the number of bytes to copy by using sizeof() multiplied by the number of items of that type to copy.

    Take care when using memcpy that the destination is big enough to contain the source data, since the compiler cannot check this for you.  In this case, the gather buffer is much bigger than the flash chip, so this is not a problem.  But always exercise caution.

    Regards,
    SJH


    On Tue, Jul 12, 2016 at 7:06 PM, Tom Kerekes tk@... [DynoMotion] <DynoMotion@yahoogroups.com> wrote:
     

    Hi Guillaume,

    Please read up about C Pointers.  You are missing some basic concepts.  In C Pointers point to memory byte addresses of objects of a certain type/size.  For example gather_buffer is defined as a pointer to doubles (which are 8 byte objects).  You are defining "p" as a pointer to a PARAMETRIC_COEFF which is a pointer to an object like 216bytes in size.   You can't write an object of one size to a memory space of an object of a different size.  So:

    gather_buffer[i]=p[i];

    is not proper.  The simplest thing would be to cast pointers to type char (bytes):

    char *p=(char *)FLASH_USER;  // pointer to the User FLASH Chip area.


    HTH
    Regards
    TK




    On 7/12/2016 8:53 AM, gyelle10@... [DynoMotion] wrote:
     
    Hi Tom,

    I can't waste the space, so I'll do the second option but I can't find many information concerning gather_buffer..

    How do I copy all flash memory into gather ? How can I specify that the kind of variable that I want to put are PARAMETRIC_COEFF ?

    Here is my program :


    //COPY ALL FLASHED PROJECT IN GATHER
    PARAMETRIC_COEFF *p=(PARAMETRIC_COEFF*)FLASHC;  // pointer to the FLASH Chip
    SetFlashBank(FLASHC); // the DSP external bus is banked, this routine selects the bank for the address 
    // now we can access the data 
    int i;
    T2=Time_sec();
    for(i=0; i<=offset; i++) //    offset is the sum of QoA_project of every previous project
    {
    gather_buffer[i]=p[i];
    }
    T3=Time_sec();
    printf ("Flash to gather Complete,time = %fs offset = %d \n",T2-T3,offset);


    Then I want to add my current project which is in the CoordMotionBuffer to the Gather_Buffer

    // ADD CURRENT PROJECT TO GATHER_BUFFER
    int j;
    for(j=0; j<=QoA_project]; j++) // QoA_project contains the number of bytes of the current project
    {
    gather_buffer[j+offset+1]=ParametricCoeffs[j];
    }


     Finally I copy the gather_buffer in flash 

    // COPY GATHER_BUFFER INTO FLASH
    T0=Time_sec();
    // write QoA_project1 bytes of the CoordMotionBuffer to the 2nd MByte of the Flash Chip
    ProgramFlash((volatile char *)ParametricCoeffs,(offset+QoA_project)/sizeof(short int),FLASH_USER,""); 
    T1=Time_sec();
    printf ("Operation Complete,time = %fs for %d bytes remaining\n",T1-T0,1000000-offset-QoA_project);
    }

    I attached the whole program,

    Thanks in advance


    Guillaume






    On Monday, July 11, 2016 7:03 PM, "Tom Kerekes tk@... [DynoMotion]" <DynoMotion@yahoogroups.com> wrote:


     
    Hi Guillaume,
    Your QoA_project value is in units of bytes the same as FLASH_USER so you should be able to simply add them together.
    However the Flash Chip works in 64K byte blocks. 16 blocks = 1 MByte.  To write even 1 word to the Flash Chip the ProgramFlash first erases the entire 64K byte block.  So it would be simplest to round the destination address up to the next 64K byte boundary.  I believe this code will do this:
     QoA_project = (QoA_project+0xffff)&(~0xffff);
    If you do not want to waste space by ounding up to the next 64KByte boundary for each project then you will need to save all the projects into temporary memory (the 8MByte gather buffer) and then Flash it all at once into the Flash Chip by calling ProgramFlash only one time.
    HTH
    Regards
    TK


    On 7/11/2016 9:56 AM, gyelle10@... [DynoMotion] wrote:
     
    Hi,

    I'm trying save the CoordMotionBuffer in the 2nd half of flash memory at specific adresses. I keep track of the number of adresses that each project needs and I want to save multiple project in Flash. So when I want to save project 2, I have to save the CoordMotionBuffer at 0x90100000 + an offset. The offset is the number of adresses needed by the 1st project. I obtain the number of adresses needed by each project when I execute them and then by :
     int QoA_project = (ParametricIndex+1)*sizeof(ParametricCoeffs[0]); //Quantity of adresses.

     My question is, how do I write to this offset ? 
    I don't understand what kind of parameter do I have to add to FLASH_USER in the ProgramFlash() fonction.


    #define FLASH_USER ((volatile char *)0x90100000)  // 2nd MegByte is for User use

    ProgramFlash((volatile char *)ParametricCoeffs,QoA_project/sizeof(short int),FLASH_USER+offset,""); 

    I have the offset computed as a double in decimal... 

    Thanks in advance,


    Guillaume
     





    Group: DynoMotion Message: 13555 From: gyelle10 Date: 7/13/2016
    Subject: Re: Writing 2nd half flash
    Hello SJH and Tom,

    I tried an other approach with your advices, I think I'm close but it still doesn't work. I use memcpy(..) to copy memory at each step :

    When I want to save a project, I do the following :
    (Note that offset is the quantity of bytes of every projects before the selected one, and QoA_object is the quantity of Bytes of the selected project)

    //COPY FLASH IN GATHER

    memcpy(gather_buffer, FLASH_USER, offset); 
    //copy memory (offset Bytes) from FLASH_USER to gather_buffer;
    // ADD CURRENT PROJECT (in CoordMotionBuffer) TO GATHER_BUFFER
    memcpy(gather_buffer+offset, &ParametricCoeffs[0], QoA_project);
     //copy memory (QoA_project Bytes) from beginning of CoordMotionBuffer to gather_buffer (after previously saved projects)

    // COPY ALL GATHER_BUFFER INTO FLASH
    memcpy(FLASH_USER, gather_buffer, offset+QoA_project);
     //Copy all the Bytes (offset+QoA_project) from gather_buffer to FLASH_USER



    And then to load a specific project I do :

    //COPY THE SPECIFIC PROJECT'S BYTES FROM FLASH TO COORD MOTION BUFFER
    memcpy(&ParametricCoeffs[0], FLASH_USER+offset, QoA_project);


    Finally, I execute the CoordMotionBuffer with :

                                    LastCoordSystem0=&ParametricCoeffs[0];
    ExecBuf();

    When I execute, the number of bytes in the CoordMotionBuffer remains the same as the last job i've done and it doesn't start. It is hard to see whats wrong because I don't know which step is wrong..

    Do you have an idea of whats wrong ?

    Thanks in advance,

    Guillaume


    On Wednesday, July 13, 2016 1:38 AM, "Hardy Family hardy.woodland.cypress@... [DynoMotion]" <DynoMotion@yahoogroups.com> wrote:


     
    Check out the bottom of
    http://dynomotion.com/Support.html
    for a list of resources for help programming C.

    Note that the memcpy() function is available (even though it may not be listed in KMotionDef.h).  memcpy() copies bytes from one location to another, without regard for the type of pointed-to objects.  For example:

    extern void * memcpy(void * dest, const void * source, unsigned int number_of_bytes);  // external definition

    (in C, void* means "pointer to an unspecified object" so you can use any pointer as a parameter in this case.)

    Then, if you want to copy from flash to the gather buffer:

    memcpy(gather_buffer, FLASH_USER, sizeof(PARAMETRIC_COEFF) * number_of_parametric_coeffs);

    where as you can see, you calculate the number of bytes to copy by using sizeof() multiplied by the number of items of that type to copy.

    Take care when using memcpy that the destination is big enough to contain the source data, since the compiler cannot check this for you.  In this case, the gather buffer is much bigger than the flash chip, so this is not a problem.  But always exercise caution.

    Regards,
    SJH


    On Tue, Jul 12, 2016 at 7:06 PM, Tom Kerekes tk@... [DynoMotion] <DynoMotion@yahoogroups.com> wrote:
     
    Hi Guillaume,
    Please read up about C Pointers.  You are missing some basic concepts.  In C Pointers point to memory byte addresses of objects of a certain type/size.  For example gather_buffer is defined as a pointer to doubles (which are 8 byte objects).  You are defining "p" as a pointer to a PARAMETRIC_COEFF which is a pointer to an object like 216bytes in size.   You can't write an object of one size to a memory space of an object of a different size.  So:
    gather_buffer[i]=p[i];
    is not proper.  The simplest thing would be to cast pointers to type char (bytes):
    char *p=(char *)FLASH_USER;  // pointer to the User FLASH Chip area.


    HTH
    Regards
    TK




    On 7/12/2016 8:53 AM, gyelle10@... [DynoMotion] wrote:
     
    Hi Tom,

    I can't waste the space, so I'll do the second option but I can't find many information concerning gather_buffer..

    How do I copy all flash memory into gather ? How can I specify that the kind of variable that I want to put are PARAMETRIC_COEFF ?

    Here is my program :


    //COPY ALL FLASHED PROJECT IN GATHER
    PARAMETRIC_COEFF *p=(PARAMETRIC_COEFF*)FLASHC;  // pointer to the FLASH Chip
    SetFlashBank(FLASHC); // the DSP external bus is banked, this routine selects the bank for the address 
    // now we can access the data 
    int i;
    T2=Time_sec();
    for(i=0; i<=offset; i++) //    offset is the sum of QoA_project of every previous project
    {
    gather_buffer[i]=p[i];
    }
    T3=Time_sec();
    printf ("Flash to gather Complete,time = %fs offset = %d \n",T2-T3,offset);


    Then I want to add my current project which is in the CoordMotionBuffer to the Gather_Buffer

    // ADD CURRENT PROJECT TO GATHER_BUFFER
    int j;
    for(j=0; j<=QoA_project]; j++) // QoA_project contains the number of bytes of the current project
    {
    gather_buffer[j+offset+1]=ParametricCoeffs[j];
    }


     Finally I copy the gather_buffer in flash 

    // COPY GATHER_BUFFER INTO FLASH
    T0=Time_sec();
    // write QoA_project1 bytes of the CoordMotionBuffer to the 2nd MByte of the Flash Chip
    ProgramFlash((volatile char *)ParametricCoeffs,(offset+QoA_project)/sizeof(short int),FLASH_USER,""); 
    T1=Time_sec();
    printf ("Operation Complete,time = %fs for %d bytes remaining\n",T1-T0,1000000-offset-QoA_project);
    }

    I attached the whole program,

    Thanks in advance


    Guillaume






    On Monday, July 11, 2016 7:03 PM, "Tom Kerekes tk@... [DynoMotion]" <DynoMotion@yahoogroups.com> wrote:


     
    Hi Guillaume,
    Your QoA_project value is in units of bytes the same as FLASH_USER so you should be able to simply add them together.
    However the Flash Chip works in 64K byte blocks. 16 blocks = 1 MByte.  To write even 1 word to the Flash Chip the ProgramFlash first erases the entire 64K byte block.  So it would be simplest to round the destination address up to the next 64K byte boundary.  I believe this code will do this:
     QoA_project = (QoA_project+0xffff)&(~0xffff);
    If you do not want to waste space by ounding up to the next 64KByte boundary for each project then you will need to save all the projects into temporary memory (the 8MByte gather buffer) and then Flash it all at once into the Flash Chip by calling ProgramFlash only one time.
    HTH
    Regards
    TK


    On 7/11/2016 9:56 AM, gyelle10@... [DynoMotion] wrote:
     
    Hi,

    I'm trying save the CoordMotionBuffer in the 2nd half of flash memory at specific adresses. I keep track of the number of adresses that each project needs and I want to save multiple project in Flash. So when I want to save project 2, I have to save the CoordMotionBuffer at 0x90100000 + an offset. The offset is the number of adresses needed by the 1st project. I obtain the number of adresses needed by each project when I execute them and then by :
     int QoA_project = (ParametricIndex+1)*sizeof(ParametricCoeffs[0]); //Quantity of adresses.

     My question is, how do I write to this offset ? 
    I don't understand what kind of parameter do I have to add to FLASH_USER in the ProgramFlash() fonction.


    #define FLASH_USER ((volatile char *)0x90100000)  // 2nd MegByte is for User use

    ProgramFlash((volatile char *)ParametricCoeffs,QoA_project/sizeof(short int),FLASH_USER+offset,""); 

    I have the offset computed as a double in decimal... 

    Thanks in advance,


    Guillaume
     







    Group: DynoMotion Message: 13556 From: Hardy Family Date: 7/13/2016
    Subject: Re: Writing 2nd half flash
    You seem to be misunderstanding the concept of pointer arithmetic.  If "offset" is a number of bytes, then "gather_buffer+offset" is not doing what you expect.  This is because gather_buffer is a pointer to double (i.e. units of 8 bytes) and the compiler will then treat "offset" as a number of doubles, rather than a number of bytes.

    The code you wrote would copy all projects (except for the first) to the wrong location in the gather buffer.  (8 times too far away).

    To avoid confusion, create some temporary variables which are pointers to byte (or char).  So don't use gather_buffer directly, but (like Tom showed before):

    char * gb = (char *)gather_buffer;

    and change
    memcpy(gather_buffer+offset, &ParametricCoeffs[0], QoA_project);
    to
    memcpy(gb+offset, &ParametricCoeffs[0], QoA_project);

    Regards,
    SJH

    On Wed, Jul 13, 2016 at 12:50 PM, gyelle10@... [DynoMotion] <DynoMotion@yahoogroups.com> wrote:
     

    Hello SJH and Tom,

    I tried an other approach with your advices, I think I'm close but it still doesn't work. I use memcpy(..) to copy memory at each step :

    When I want to save a project, I do the following :
    (Note that offset is the quantity of bytes of every projects before the selected one, and QoA_object is the quantity of Bytes of the selected project)

    //COPY FLASH IN GATHER

    memcpy(gather_buffer, FLASH_USER, offset); 
    //copy memory (offset Bytes) from FLASH_USER to gather_buffer;
    // ADD CURRENT PROJECT (in CoordMotionBuffer) TO GATHER_BUFFER
    memcpy(gather_buffer+offset, &ParametricCoeffs[0], QoA_project);
     //copy memory (QoA_project Bytes) from beginning of CoordMotionBuffer to gather_buffer (after previously saved projects)

    // COPY ALL GATHER_BUFFER INTO FLASH
    memcpy(FLASH_USER, gather_buffer, offset+QoA_project);
     //Copy all the Bytes (offset+QoA_project) from gather_buffer to FLASH_USER



    And then to load a specific project I do :

    //COPY THE SPECIFIC PROJECT'S BYTES FROM FLASH TO COORD MOTION BUFFER
    memcpy(&ParametricCoeffs[0], FLASH_USER+offset, QoA_project);


    Finally, I execute the CoordMotionBuffer with :

                                    LastCoordSystem0=&ParametricCoeffs[0];
    ExecBuf();

    When I execute, the number of bytes in the CoordMotionBuffer remains the same as the last job i've done and it doesn't start. It is hard to see whats wrong because I don't know which step is wrong..

    Do you have an idea of whats wrong ?

    Thanks in advance,

    Guillaume


    On Wednesday, July 13, 2016 1:38 AM, "Hardy Family hardy.woodland.cypress@... [DynoMotion]" <DynoMotion@yahoogroups.com> wrote:


     
    Check out the bottom of
    http://dynomotion.com/Support.html
    for a list of resources for help programming C.

    Note that the memcpy() function is available (even though it may not be listed in KMotionDef.h).  memcpy() copies bytes from one location to another, without regard for the type of pointed-to objects.  For example:

    extern void * memcpy(void * dest, const void * source, unsigned int number_of_bytes);  // external definition

    (in C, void* means "pointer to an unspecified object" so you can use any pointer as a parameter in this case.)

    Then, if you want to copy from flash to the gather buffer:

    memcpy(gather_buffer, FLASH_USER, sizeof(PARAMETRIC_COEFF) * number_of_parametric_coeffs);

    where as you can see, you calculate the number of bytes to copy by using sizeof() multiplied by the number of items of that type to copy.

    Take care when using memcpy that the destination is big enough to contain the source data, since the compiler cannot check this for you.  In this case, the gather buffer is much bigger than the flash chip, so this is not a problem.  But always exercise caution.

    Regards,
    SJH


    On Tue, Jul 12, 2016 at 7:06 PM, Tom Kerekes tk@... [DynoMotion] <DynoMotion@yahoogroups.com> wrote:
     
    Hi Guillaume,
    Please read up about C Pointers.  You are missing some basic concepts.  In C Pointers point to memory byte addresses of objects of a certain type/size.  For example gather_buffer is defined as a pointer to doubles (which are 8 byte objects).  You are defining "p" as a pointer to a PARAMETRIC_COEFF which is a pointer to an object like 216bytes in size.   You can't write an object of one size to a memory space of an object of a different size.  So:
    gather_buffer[i]=p[i];
    is not proper.  The simplest thing would be to cast pointers to type char (bytes):
    char *p=(char *)FLASH_USER;  // pointer to the User FLASH Chip area.


    HTH
    Regards
    TK




    On 7/12/2016 8:53 AM, gyelle10@... [DynoMotion] wrote:
     
    Hi Tom,

    I can't waste the space, so I'll do the second option but I can't find many information concerning gather_buffer..

    How do I copy all flash memory into gather ? How can I specify that the kind of variable that I want to put are PARAMETRIC_COEFF ?

    Here is my program :


    //COPY ALL FLASHED PROJECT IN GATHER
    PARAMETRIC_COEFF *p=(PARAMETRIC_COEFF*)FLASHC;  // pointer to the FLASH Chip
    SetFlashBank(FLASHC); // the DSP external bus is banked, this routine selects the bank for the address 
    // now we can access the data 
    int i;
    T2=Time_sec();
    for(i=0; i<=offset; i++) //    offset is the sum of QoA_project of every previous project
    {
    gather_buffer[i]=p[i];
    }
    T3=Time_sec();
    printf ("Flash to gather Complete,time = %fs offset = %d \n",T2-T3,offset);


    Then I want to add my current project which is in the CoordMotionBuffer to the Gather_Buffer

    // ADD CURRENT PROJECT TO GATHER_BUFFER
    int j;
    for(j=0; j<=QoA_project]; j++) // QoA_project contains the number of bytes of the current project
    {
    gather_buffer[j+offset+1]=ParametricCoeffs[j];
    }


     Finally I copy the gather_buffer in flash 

    // COPY GATHER_BUFFER INTO FLASH
    T0=Time_sec();
    // write QoA_project1 bytes of the CoordMotionBuffer to the 2nd MByte of the Flash Chip
    ProgramFlash((volatile char *)ParametricCoeffs,(offset+QoA_project)/sizeof(short int),FLASH_USER,""); 
    T1=Time_sec();
    printf ("Operation Complete,time = %fs for %d bytes remaining\n",T1-T0,1000000-offset-QoA_project);
    }

    I attached the whole program,

    Thanks in advance


    Guillaume






    On Monday, July 11, 2016 7:03 PM, "Tom Kerekes tk@... [DynoMotion]" <DynoMotion@yahoogroups.com> wrote:


     
    Hi Guillaume,
    Your QoA_project value is in units of bytes the same as FLASH_USER so you should be able to simply add them together.
    However the Flash Chip works in 64K byte blocks. 16 blocks = 1 MByte.  To write even 1 word to the Flash Chip the ProgramFlash first erases the entire 64K byte block.  So it would be simplest to round the destination address up to the next 64K byte boundary.  I believe this code will do this:
     QoA_project = (QoA_project+0xffff)&(~0xffff);
    If you do not want to waste space by ounding up to the next 64KByte boundary for each project then you will need to save all the projects into temporary memory (the 8MByte gather buffer) and then Flash it all at once into the Flash Chip by calling ProgramFlash only one time.
    HTH
    Regards
    TK


    On 7/11/2016 9:56 AM, gyelle10@... [DynoMotion] wrote:
     
    Hi,

    I'm trying save the CoordMotionBuffer in the 2nd half of flash memory at specific adresses. I keep track of the number of adresses that each project needs and I want to save multiple project in Flash. So when I want to save project 2, I have to save the CoordMotionBuffer at 0x90100000 + an offset. The offset is the number of adresses needed by the 1st project. I obtain the number of adresses needed by each project when I execute them and then by :
     int QoA_project = (ParametricIndex+1)*sizeof(ParametricCoeffs[0]); //Quantity of adresses.

     My question is, how do I write to this offset ? 
    I don't understand what kind of parameter do I have to add to FLASH_USER in the ProgramFlash() fonction.


    #define FLASH_USER ((volatile char *)0x90100000)  // 2nd MegByte is for User use

    ProgramFlash((volatile char *)ParametricCoeffs,QoA_project/sizeof(short int),FLASH_USER+offset,""); 

    I have the offset computed as a double in decimal... 

    Thanks in advance,


    Guillaume
     








    Group: DynoMotion Message: 13564 From: gyelle10 Date: 7/14/2016
    Subject: Re: Writing 2nd half flash
    You are right, my base in C are not very strong.. at least I understand what you are saying and I read on pointer.

    I tried it but it still not work.. What does the memcpy() function do exactly ?  How I see it is for the first function (COPY FLASH IN GATHER), memcpy() takes the first "offset" bytes starting at FLASH_USER. and copy starting at beginning  of gb (gather_buffer). Because FLASH_USER and gb point to 1 byte memory case, each copied bytes follow each others by 1 adress.
    //COPY FLASH IN GATHER
    memcpy(gb, FLASH_USER, offset); 

            
    The  ADD CURRENT PROJECT TO GATHER_BUFFER function does the same but copy exacly what is currently in the CoordMotionBuffe (QoA_project bytes, which include the terminated segment) byte per byte. Even if ParametricCoeffs points to 216 bytes arguments, it will copy 1 byte at a time because the pointer is char * coeffs. It will copy theses bytes to gb+offset, which means after the previously copied bytes in the gather_buffer. (The first project will start at gb).
    // ADD CURRENT PROJECT TO GATHER_BUFFER
    memcpy(gb+offset, coeffs,QoA_project); 


    The COPY GATHER_BUFFER INTO FLASH copies all what have been copied in the gather_buffer in the flash memory. To do so, it copy the offset+QoA_project starting at gb to the beginning of FLASH_USER (The first project will start at FLASH_USER).
    // COPY GATHER_BUFFER INTO FLASH
    memcpy(FLASH_USER, gb, offset+QoA_project);



    I execute these 3 functions in a thread named "SaveJob.C". The header of this thread is the following :

            persist.UserData[0]=1; //Save project number 1
    int project = persist.UserData[0]; //Put the project number in persist Data
    int QoA_project = (ParametricIndex+1)*sizeof(ParametricCoeffs[0]); //Quantity of bytes to save.
    persist.UserData[project] = QoA_project; // Keep track of the number of bytes of this project.
    int offset = get_offset(); // Bytes of every previously saved project 
    char * gb = (char *)gather_buffer;  // Pointer of 1 bytes starting at beginning of gather_buffer
            char * coeffs = (char *) ParametricCoeffs; // Pointer of 1 bytes starting at beginning of ParametricCoeffs

    Where the get_offset(); function is the following (It works fine, I tested it) :

    int get_offset()
    {
    int offset = 0;
    int p;
    if (persist.UserData[0]==1)     //persist.UserData[0] contains the project number
    offset=0;
    else {
    for (p = (persist.UserData[0])-1;p>0;p--)
    {
    offset += persist.UserData[p];  // persist.UserData[p] contains the QoA_project (number of bytes) of                                                                      //  the project.
    }
    }
    return offset;
    }


    Finally, I use another thread (LoadJob.C) that contains the following function :

            //COPY SPECIFIC PROJECT'S BYTES FROM FLASH TO COORD MOTION BUFFER
    memcpy(coeffs,FLASH_USER+offset,QoA_project);

    This function copy QoA_project  bytes (which is the number of bytes needed by the selected project) from FLASH_USER+offset (where the project is supposed to be in the flash memory) to the beginning of the Coord Motion Buffer.

    When I execute these threads, ( I save 2 different project and then I load the first one), and then I execute the CoordMotionBuffer:  LastCoordSystem0=&ParametricCoeffs[0];
    ExecBuf();

    which should contain the project 1 because of memcpy(coeffs,FLASH_USER+offset,QoA_project); , The offset and QoA_project are good in the persist data but the real number of bytes in the CoordMotionBuffer:(ParametricIndex+1)*sizeof(ParametricCoeffs[0]); 

    is still the same as the last executed job (project 2) and it do not even execute... I changed the persist.UserData[0] (contains the number of the project between each saving process to be sure to not overwrite on previous project.

    I'm sorry for the long message I wanted to detail more then less, I really need it to work. ( I attached my C files)

    Thanks for your support,

    Guillaume























    On Wednesday, July 13, 2016 5:07 PM, "Hardy Family hardy.woodland.cypress@... [DynoMotion]" <DynoMotion@yahoogroups.com> wrote:


     
    You seem to be misunderstanding the concept of pointer arithmetic.  If "offset" is a number of bytes, then "gather_buffer+offset" is not doing what you expect.  This is because gather_buffer is a pointer to double (i.e. units of 8 bytes) and the compiler will then treat "offset" as a number of doubles, rather than a number of bytes.

    The code you wrote would copy all projects (except for the first) to the wrong location in the gather buffer.  (8 times too far away).

    To avoid confusion, create some temporary variables which are pointers to byte (or char).  So don't use gather_buffer directly, but (like Tom showed before):

    char * gb = (char *)gather_buffer;

    and change
    memcpy(gather_buffer+offset, &ParametricCoeffs[0], QoA_project);
    to
    memcpy(gb+offset, &ParametricCoeffs[0], QoA_project);

    Regards,
    SJH

    On Wed, Jul 13, 2016 at 12:50 PM, gyelle10@... [DynoMotion] <DynoMotion@yahoogroups.com> wrote:
     
    Hello SJH and Tom,

    I tried an other approach with your advices, I think I'm close but it still doesn't work. I use memcpy(..) to copy memory at each step :

    When I want to save a project, I do the following :
    (Note that offset is the quantity of bytes of every projects before the selected one, and QoA_object is the quantity of Bytes of the selected project)

    //COPY FLASH IN GATHER

    memcpy(gather_buffer, FLASH_USER, offset); 
    //copy memory (offset Bytes) from FLASH_USER to gather_buffer;
    // ADD CURRENT PROJECT (in CoordMotionBuffer) TO GATHER_BUFFER
    memcpy(gather_buffer+offset, &ParametricCoeffs[0], QoA_project);
     //copy memory (QoA_project Bytes) from beginning of CoordMotionBuffer to gather_buffer (after previously saved projects)

    // COPY ALL GATHER_BUFFER INTO FLASH
    memcpy(FLASH_USER, gather_buffer, offset+QoA_project);
     //Copy all the Bytes (offset+QoA_project) from gather_buffer to FLASH_USER



    And then to load a specific project I do :

    //COPY THE SPECIFIC PROJECT'S BYTES FROM FLASH TO COORD MOTION BUFFER
    memcpy(&ParametricCoeffs[0], FLASH_USER+offset, QoA_project);


    Finally, I execute the CoordMotionBuffer with :

                                    LastCoordSystem0=&ParametricCoeffs[0];
    ExecBuf();

    When I execute, the number of bytes in the CoordMotionBuffer remains the same as the last job i've done and it doesn't start. It is hard to see whats wrong because I don't know which step is wrong..

    Do you have an idea of whats wrong ?

    Thanks in advance,

    Guillaume


    On Wednesday, July 13, 2016 1:38 AM, "Hardy Family hardy.woodland.cypress@... [DynoMotion]" <DynoMotion@yahoogroups.com> wrote:


     
    Check out the bottom of
    http://dynomotion.com/Support.html
    for a list of resources for help programming C.

    Note that the memcpy() function is available (even though it may not be listed in KMotionDef.h).  memcpy() copies bytes from one location to another, without regard for the type of pointed-to objects.  For example:

    extern void * memcpy(void * dest, const void * source, unsigned int number_of_bytes);  // external definition

    (in C, void* means "pointer to an unspecified object" so you can use any pointer as a parameter in this case.)

    Then, if you want to copy from flash to the gather buffer:

    memcpy(gather_buffer, FLASH_USER, sizeof(PARAMETRIC_COEFF) * number_of_parametric_coeffs);

    where as you can see, you calculate the number of bytes to copy by using sizeof() multiplied by the number of items of that type to copy.

    Take care when using memcpy that the destination is big enough to contain the source data, since the compiler cannot check this for you.  In this case, the gather buffer is much bigger than the flash chip, so this is not a problem.  But always exercise caution.

    Regards,
    SJH


    On Tue, Jul 12, 2016 at 7:06 PM, Tom Kerekes tk@... [DynoMotion] <DynoMotion@yahoogroups.com> wrote:
     
    Hi Guillaume,
    Please read up about C Pointers.  You are missing some basic concepts.  In C Pointers point to memory byte addresses of objects of a certain type/size.  For example gather_buffer is defined as a pointer to doubles (which are 8 byte objects).  You are defining "p" as a pointer to a PARAMETRIC_COEFF which is a pointer to an object like 216bytes in size.   You can't write an object of one size to a memory space of an object of a different size.  So:
    gather_buffer[i]=p[i];
    is not proper.  The simplest thing would be to cast pointers to type char (bytes):
    char *p=(char *)FLASH_USER;  // pointer to the User FLASH Chip area.


    HTH
    Regards
    TK




    On 7/12/2016 8:53 AM, gyelle10@... [DynoMotion] wrote:
     
    Hi Tom,

    I can't waste the space, so I'll do the second option but I can't find many information concerning gather_buffer..

    How do I copy all flash memory into gather ? How can I specify that the kind of variable that I want to put are PARAMETRIC_COEFF ?

    Here is my program :


    //COPY ALL FLASHED PROJECT IN GATHER
    PARAMETRIC_COEFF *p=(PARAMETRIC_COEFF*)FLASHC;  // pointer to the FLASH Chip
    SetFlashBank(FLASHC); // the DSP external bus is banked, this routine selects the bank for the address 
    // now we can access the data 
    int i;
    T2=Time_sec();
    for(i=0; i<=offset; i++) //    offset is the sum of QoA_project of every previous project
    {
    gather_buffer[i]=p[i];
    }
    T3=Time_sec();
    printf ("Flash to gather Complete,time = %fs offset = %d \n",T2-T3,offset);


    Then I want to add my current project which is in the CoordMotionBuffer to the Gather_Buffer

    // ADD CURRENT PROJECT TO GATHER_BUFFER
    int j;
    for(j=0; j<=QoA_project]; j++) // QoA_project contains the number of bytes of the current project
    {
    gather_buffer[j+offset+1]=ParametricCoeffs[j];
    }


     Finally I copy the gather_buffer in flash 

    // COPY GATHER_BUFFER INTO FLASH
    T0=Time_sec();
    // write QoA_project1 bytes of the CoordMotionBuffer to the 2nd MByte of the Flash Chip
    ProgramFlash((volatile char *)ParametricCoeffs,(offset+QoA_project)/sizeof(short int),FLASH_USER,""); 
    T1=Time_sec();
    printf ("Operation Complete,time = %fs for %d bytes remaining\n",T1-T0,1000000-offset-QoA_project);
    }

    I attached the whole program,

    Thanks in advance


    Guillaume






    On Monday, July 11, 2016 7:03 PM, "Tom Kerekes tk@... [DynoMotion]" <DynoMotion@yahoogroups.com> wrote:


     
    Hi Guillaume,
    Your QoA_project value is in units of bytes the same as FLASH_USER so you should be able to simply add them together.
    However the Flash Chip works in 64K byte blocks. 16 blocks = 1 MByte.  To write even 1 word to the Flash Chip the ProgramFlash first erases the entire 64K byte block.  So it would be simplest to round the destination address up to the next 64K byte boundary.  I believe this code will do this:
     QoA_project = (QoA_project+0xffff)&(~0xffff);
    If you do not want to waste space by ounding up to the next 64KByte boundary for each project then you will need to save all the projects into temporary memory (the 8MByte gather buffer) and then Flash it all at once into the Flash Chip by calling ProgramFlash only one time.
    HTH
    Regards
    TK


    On 7/11/2016 9:56 AM, gyelle10@... [DynoMotion] wrote:


    (Message over 64 KB, truncated)
      @@attachment@@
    Group: DynoMotion Message: 13569 From: Tom Kerekes Date: 7/14/2016
    Subject: Re: Writing 2nd half flash [3 Attachments]

    Hi Guillaume,

    It seems your SaveJob.c program is trying to memcpy the data to the Flash Chip.  The Flash is read only memory and is also memory banked.  Use The ProgramFlash function to write data to the Flash chip.

    Another problem is that the Flash chip is banked in 16KByte banks.  memcpy does not know this.  It will not set the bank and update the bank when it crosses 16KByte boundaries.  You will need to do this.  The simplest thing would be to just use a for loop to move the memory one byte at a time and update the Flash bank every byte.  That may be slow.  Once you get it working correctly you can optimize it to do memcpy bursts of 16KBytes.

    There may be some variables that need to be properly set for each project.  Such as:

    extern double CS0_TimeDownloaded;    // Sum of all Coord Motion Segments downloaded from Host
    extern double CS0_TimeLost;            // Sum of all Coord Motion Segments downloaded from Host that have been discarded (buffer wrap)

    Those are all I can think of.  CS0_TimeLost should aways be set to zero because all your data is assumed to be less than one full buffer.

    The length of the data isn't required because there is a termination segment at the end.

    HTH

    Regards

    TK




    On 7/14/2016 8:14 AM, gyelle10@... [DynoMotion] wrote:
     
    You are right, my base in C are not very strong.. at least I understand what you are saying and I read on pointer.

    I tried it but it still not work.. What does the memcpy() function do exactly ?  How I see it is for the first function (COPY FLASH IN GATHER), memcpy() takes the first "offset" bytes starting at FLASH_USER. and copy starting at beginning  of gb (gather_buffer). Because FLASH_USER and gb point to 1 byte memory case, each copied bytes follow each others by 1 adress.
    //COPY FLASH IN GATHER
    memcpy(gb, FLASH_USER, offset); 

            
    The  ADD CURRENT PROJECT TO GATHER_BUFFER function does the same but copy exacly what is currently in the CoordMotionBuffe (QoA_project bytes, which include the terminated segment) byte per byte. Even if ParametricCoeffs points to 216 bytes arguments, it will copy 1 byte at a time because the pointer is char * coeffs. It will copy theses bytes to gb+offset, which means after the previously copied bytes in the gather_buffer. (The first project will start at gb).
    // ADD CURRENT PROJECT TO GATHER_BUFFER
    memcpy(gb+offset, coeffs,QoA_project); 


    The COPY GATHER_BUFFER INTO FLASH copies all what have been copied in the gather_buffer in the flash memory. To do so, it copy the offset+QoA_project starting at gb to the beginning of FLASH_USER (The first project will start at FLASH_USER).
    // COPY GATHER_BUFFER INTO FLASH
    memcpy(FLASH_USER, gb, offset+QoA_project);



    I execute these 3 functions in a thread named "SaveJob.C". The header of this thread is the following :

            persist.UserData[0]=1; //Save project number 1
    int project = persist.UserData[0]; //Put the project number in persist Data
    int QoA_project = (ParametricIndex+1)*sizeof(ParametricCoeffs[0]); //Quantity of bytes to save.
    persist.UserData[project] = QoA_project; // Keep track of the number of bytes of this project.
    int offset = get_offset(); // Bytes of every previously saved project 
    char * gb = (char *)gather_buffer;  // Pointer of 1 bytes starting at beginning of gather_buffer
            char * coeffs = (char *) ParametricCoeffs; // Pointer of 1 bytes starting at beginning of ParametricCoeffs

    Where the get_offset(); function is the following (It works fine, I tested it) :

    int get_offset()
    {
    int offset = 0;
    int p;
    if (persist.UserData[0]==1)     //persist.UserData[0] contains the project number
    offset=0;
    else {
    for (p = (persist.UserData[0])-1;p>0;p--)
    {
    offset += persist.UserData[p];  // persist.UserData[p] contains the QoA_project (number of bytes) of                                                                      //  the project.
    }
    }
    return offset;
    }


    Finally, I use another thread (LoadJob.C) that contains the following function :

            //COPY SPECIFIC PROJECT'S BYTES FROM FLASH TO COORD MOTION BUFFER
    memcpy(coeffs,FLASH_USER+offset,QoA_project);

    This function copy QoA_project  bytes (which is the number of bytes needed by the selected project) from FLASH_USER+offset (where the project is supposed to be in the flash memory) to the beginning of the Coord Motion Buffer.

    When I execute these threads, ( I save 2 different project and then I load the first one), and then I execute the CoordMotionBuffer:  LastCoordSystem0=&ParametricCoeffs[0];
    ExecBuf();

    which should contain the project 1 because of memcpy(coeffs,FLASH_USER+offset,QoA_project); , The offset and QoA_project are good in the persist data but the real number of bytes in the CoordMotionBuffer:(ParametricIndex+1)*sizeof(ParametricCoeffs[0]); 

    is still the same as the last executed job (project 2) and it do not even execute... I changed the persist.UserData[0] (contains the number of the project between each saving process to be sure to not overwrite on previous project.

    I'm sorry for the long message I wanted to detail more then less, I really need it to work. ( I attached my C files)

    Thanks for your support,

    Guillaume























    On Wednesday, July 13, 2016 5:07 PM, "Hardy Family hardy.woodland.cypress@... [DynoMotion]" <DynoMotion@yahoogroups.com> wrote:


     
    You seem to be misunderstanding the concept of pointer arithmetic.  If "offset" is a number of bytes, then "gather_buffer+offset" is not doing what you expect.  This is because gather_buffer is a pointer to double (i.e. units of 8 bytes) and the compiler will then treat "offset" as a number of doubles, rather than a number of bytes.

    The code you wrote would copy all projects (except for the first) to the wrong location in the gather buffer.  (8 times too far away).

    To avoid confusion, create some temporary variables which are pointers to byte (or char).  So don't use gather_buffer directly, but (like Tom showed before):

    char * gb = (char *)gather_buffer;

    and change
    memcpy(gather_buffer+offset, &ParametricCoeffs[0], QoA_project);
    to
    memcpy(gb+offset, &ParametricCoeffs[0], QoA_project);

    Regards,
    SJH

    On Wed, Jul 13, 2016 at 12:50 PM, gyelle10@... [DynoMotion] <DynoMotion@yahoogroups.com> wrote:
     
    Hello SJH and Tom,

    I tried an other approach with your advices, I think I'm close but it still doesn't work. I use memcpy(..) to copy memory at each step :

    When I want to save a project, I do the following :
    (Note that offset is the quantity of bytes of every projects before the selected one, and QoA_object is the quantity of Bytes of the selected project)

    //COPY FLASH IN GATHER

    Group: DynoMotion Message: 13574 From: gyelle10 Date: 7/14/2016
    Subject: Re: Writing 2nd half flash
    Hi Tom,

    I allready had changed for the ProgramFlash function to write data :) 

    You wrote that Flash chip is banked in 16KByte banks, is this an error ? isn't it 64KByte ? Anyway, the Flash Bank is not clear to me. It sets the currentrly addressable flash bank, so to update the Flash bank every byte I write SetFlashBank(FLASH_USER+1 byte) at each byte ? Here is my for loop to copy flash in gather_buffer or in CoordMotionBuffer :

    char * gb = (char *)gather_buffer;  // Pointer of 1 bytes starting at beginning of gather_buffer
    char * coeffs = (char *) ParametricCoeffs; // Pointer of 1 bytes starting at beginning of ParametricCoeffs
    char *p=(char *)FLASH_USER;  // pointer to the User FLASH Chip area.

    for (i=0; i<=offset; i++)
    {
    SetFlashBank(FLASH_USER+1);
    gb[i]=p[i];
    }
    And to copy from flash to coord Motion Buffer :

    for (i=0; i<=QoA_project; i++)
    {
    SetFlashBank(FLASH_USER+i);
    coeffs[i]=p[i+offset];
    }

    It works fine for but only for first ~16Kbytes so I guess you were right about 16Kbytes ! I also guess that my SetFlashBank is not set properly.. 

    Thanks in advance,

    Guillaume

     


    On Thursday, July 14, 2016 1:10 PM, "Tom Kerekes tk@... [DynoMotion]" <DynoMotion@yahoogroups.com> wrote:


     
    Hi Guillaume,
    It seems your SaveJob.c program is trying to memcpy the data to the Flash Chip.  The Flash is read only memory and is also memory banked.  Use The ProgramFlash function to write data to the Flash chip.
    Another problem is that the Flash chip is banked in 16KByte banks.  memcpy does not know this.  It will not set the bank and update the bank when it crosses 16KByte boundaries.  You will need to do this.  The simplest thing would be to just use a for loop to move the memory one byte at a time and update the Flash bank every byte.  That may be slow.  Once you get it working correctly you can optimize it to do memcpy bursts of 16KBytes.
    There may be some variables that need to be properly set for each project.  Such as:
    extern double CS0_TimeDownloaded;    // Sum of all Coord Motion Segments downloaded from Host
    extern double CS0_TimeLost;            // Sum of all Coord Motion Segments downloaded from Host that have been discarded (buffer wrap)
    Those are all I can think of.  CS0_TimeLost should aways be set to zero because all your data is assumed to be less than one full buffer.
    The length of the data isn't required because there is a termination segment at the end.
    HTH
    Regards
    TK



    On 7/14/2016 8:14 AM, gyelle10@... [DynoMotion] wrote:
     
    You are right, my base in C are not very strong.. at least I understand what you are saying and I read on pointer.

    I tried it but it still not work.. What does the memcpy() function do exactly ?  How I see it is for the first function (COPY FLASH IN GATHER), memcpy() takes the first "offset" bytes starting at FLASH_USER. and copy starting at beginning  of gb (gather_buffer). Because FLASH_USER and gb point to 1 byte memory case, each copied bytes follow each others by 1 adress.
    //COPY FLASH IN GATHER
    memcpy(gb, FLASH_USER, offset); 

            
    The  ADD CURRENT PROJECT TO GATHER_BUFFER function does the same but copy exacly what is currently in the CoordMotionBuffe (QoA_project bytes, which include the terminated segment) byte per byte. Even if ParametricCoeffs points to 216 bytes arguments, it will copy 1 byte at a time because the pointer is char * coeffs. It will copy theses bytes to gb+offset, which means after the previously copied bytes in the gather_buffer. (The first project will start at gb).
    // ADD CURRENT PROJECT TO GATHER_BUFFER
    memcpy(gb+offset, coeffs,QoA_project); 


    The COPY GATHER_BUFFER INTO FLASH copies all what have been copied in the gather_buffer in the flash memory. To do so, it copy the offset+QoA_project starting at gb to the beginning of FLASH_USER (The first project will start at FLASH_USER).
    // COPY GATHER_BUFFER INTO FLASH
    memcpy(FLASH_USER, gb, offset+QoA_project);



    I execute these 3 functions in a thread named "SaveJob.C". The header of this thread is the following :

            persist.UserData[0]=1; //Save project number 1
    int project = persist.UserData[0]; //Put the project number in persist Data
    int QoA_project = (ParametricIndex+1)*sizeof(ParametricCoeffs[0]); //Quantity of bytes to save.
    persist.UserData[project] = QoA_project; // Keep track of the number of bytes of this project.
    int offset = get_offset(); // Bytes of every previously saved project 
    char * gb = (char *)gather_buffer;  // Pointer of 1 bytes starting at beginning of gather_buffer
            char * coeffs = (char *) ParametricCoeffs; // Pointer of 1 bytes starting at beginning of ParametricCoeffs

    Where the get_offset(); function is the following (It works fine, I tested it) :

    int get_offset()
    {
    int offset = 0;
    int p;
    if (persist.UserData[0]==1)     //persist.UserData[0] contains the project number
    offset=0;
    else {
    for (p = (persist.UserData[0])-1;p>0;p--)
    {
    offset += persist.UserData[p];  // persist.UserData[p] contains the QoA_project (number of bytes) of                                                                      //  the project.
    }
    }
    return offset;
    }


    Finally, I use another thread (LoadJob.C) that contains the following function :

            //COPY SPECIFIC PROJECT'S BYTES FROM FLASH TO COORD MOTION BUFFER
    memcpy(coeffs,FLASH_USER+offset,QoA_project);

    This function copy QoA_project  bytes (which is the number of bytes needed by the selected project) from FLASH_USER+offset (where the project is supposed to be in the flash memory) to the beginning of the Coord Motion Buffer.

    When I execute these threads, ( I save 2 different project and then I load the first one), and then I execute the CoordMotionBuffer:  LastCoordSystem0=&ParametricCoeffs[0];
    ExecBuf();

    which should contain the project 1 because of memcpy(coeffs,FLASH_USER+offset,QoA_project); , The offset and QoA_project are good in the persist data but the real number of bytes in the CoordMotionBuffer:(ParametricIndex+1)*sizeof(ParametricCoeffs[0]); 

    is still the same as the last executed job (project 2) and it do not even execute... I changed the persist.UserData[0] (contains the number of the project between each saving process to be sure to not overwrite on previous project.

    I'm sorry for the long message I wanted to detail more then less, I really need it to work. ( I attached my C files)

    Thanks for your support,

    Guillaume























    On Wednesday, July 13, 2016 5:07 PM, "Hardy Family hardy.woodland.cypress@... [DynoMotion]" <DynoMotion@yahoogroups.com> wrote:


     
    You seem to be misunderstanding the concept of pointer arithmetic.  If "offset" is a number of bytes, then "gather_buffer+offset" is not doing what you expect.  This is because gather_buffer is a pointer to double (i.e. units of 8 bytes) and the compiler will then treat "offset" as a number of doubles, rather than a number of bytes.

    The code you wrote would copy all projects (except for the first) to the wrong location in the gather buffer.  (8 times too far away).

    To avoid confusion, create some temporary variables which are pointers to byte (or char).  So don't use gather_buffer directly, but (like Tom showed before):

    char * gb = (char *)gather_buffer;

    and change
    memcpy(gather_buffer+offset, &ParametricCoeffs[0], QoA_project);
    to
    memcpy(gb+offset, &ParametricCoeffs[0], QoA_project);

    Regards,
    SJH

    On Wed, Jul 13, 2016 at 12:50 PM, gyelle10@... [DynoMotion] <DynoMotion@yahoogroups.com> wrote:
     
    Hello SJH and Tom,

    I tried an other approach with your advices, I think I'm close but it still doesn't work. I use memcpy(..) to copy memory at each step :

    When I want to save a project, I do the following :
    (Note that offset is the quantity of bytes of every projects before the selected one, and QoA_object is the quantity of Bytes of the selected project)

    //COPY FLASH IN GATHER

    memcpy(gather_buffer, FLASH_USER, offset); 
    //copy memory (offset Bytes) from FLASH_USER to gather_buffer;
    // ADD CURRENT PROJECT (in CoordMotionBuffer) TO GATHER_BUFFER
    memcpy(gather_buffer+offset, &ParametricCoeffs[0], QoA_project);


    (Message over 64 KB, truncated)
    Group: DynoMotion Message: 13575 From: Hardy Family Date: 7/14/2016
    Subject: Re: Writing 2nd half flash
    You need to call SetFlashBank with the address you are going to access, your code is always using the same address each time (in first loop) and ignoring the offset in the second loop.

    How about you write a function which copies any amount of data from flash to other memory.  Something like this:

    void memcpy_from_user_flash(void * dest, int byte_offset_in_user_flash, int num_bytes)
    {
      const char * f = (const char *)FLASH_USER + byte_offset_in_user_flash;
      char * m = (char *)dest;

      while (num_bytes > 0) {
        SetFlashBank(f);
        *m++ = *f++;
        --num_bytes;
      }
    }

    This is simple and inefficient, but "premature optimization is the root of all evil"...

    Regards,
    SJH


    On Thu, Jul 14, 2016 at 12:24 PM, gyelle10@... [DynoMotion] <DynoMotion@yahoogroups.com> wrote:
     

    Hi Tom,

    I allready had changed for the ProgramFlash function to write data :) 

    You wrote that Flash chip is banked in 16KByte banks, is this an error ? isn't it 64KByte ? Anyway, the Flash Bank is not clear to me. It sets the currentrly addressable flash bank, so to update the Flash bank every byte I write SetFlashBank(FLASH_USER+1 byte) at each byte ? Here is my for loop to copy flash in gather_buffer or in CoordMotionBuffer :

    char * gb = (char *)gather_buffer;  // Pointer of 1 bytes starting at beginning of gather_buffer
    char * coeffs = (char *) ParametricCoeffs; // Pointer of 1 bytes starting at beginning of ParametricCoeffs
    char *p=(char *)FLASH_USER;  // pointer to the User FLASH Chip area.

    for (i=0; i<=offset; i++)
    {
    SetFlashBank(FLASH_USER+1);
    gb[i]=p[i];
    }
    And to copy from flash to coord Motion Buffer :

    for (i=0; i<=QoA_project; i++)
    {
    SetFlashBank(FLASH_USER+i);
    coeffs[i]=p[i+offset];
    }

    It works fine for but only for first ~16Kbytes so I guess you were right about 16Kbytes ! I also guess that my SetFlashBank is not set properly.. 

    Thanks in advance,

    Guillaume

     


    On Thursday, July 14, 2016 1:10 PM, "Tom Kerekes tk@... [DynoMotion]" <DynoMotion@yahoogroups.com> wrote:


     
    Hi Guillaume,
    It seems your SaveJob.c program is trying to memcpy the data to the Flash Chip.  The Flash is read only memory and is also memory banked.  Use The ProgramFlash function to write data to the Flash chip.
    Another problem is that the Flash chip is banked in 16KByte banks.  memcpy does not know this.  It will not set the bank and update the bank when it crosses 16KByte boundaries.  You will need to do this.  The simplest thing would be to just use a for loop to move the memory one byte at a time and update the Flash bank every byte.  That may be slow.  Once you get it working correctly you can optimize it to do memcpy bursts of 16KBytes.
    There may be some variables that need to be properly set for each project.  Such as:
    extern double CS0_TimeDownloaded;    // Sum of all Coord Motion Segments downloaded from Host
    extern double CS0_TimeLost;            // Sum of all Coord Motion Segments downloaded from Host that have been discarded (buffer wrap)
    Those are all I can think of.  CS0_TimeLost should aways be set to zero because all your data is assumed to be less than one full buffer.
    The length of the data isn't required because there is a termination segment at the end.
    HTH
    Regards
    TK



    On 7/14/2016 8:14 AM, gyelle10@... [DynoMotion] wrote:
     
    You are right, my base in C are not very strong.. at least I understand what you are saying and I read on pointer.

    I tried it but it still not work.. What does the memcpy() function do exactly ?  How I see it is for the first function (COPY FLASH IN GATHER), memcpy() takes the first "offset" bytes starting at FLASH_USER. and copy starting at beginning  of gb (gather_buffer). Because FLASH_USER and gb point to 1 byte memory case, each copied bytes follow each others by 1 adress.
    //COPY FLASH IN GATHER
    memcpy(gb, FLASH_USER, offset); 

            
    The  ADD CURRENT PROJECT TO GATHER_BUFFER function does the same but copy exacly what is currently in the CoordMotionBuffe (QoA_project bytes, which include the terminated segment) byte per byte. Even if ParametricCoeffs points to 216 bytes arguments, it will copy 1 byte at a time because the pointer is char * coeffs. It will copy theses bytes to gb+offset, which means after the previously copied bytes in the gather_buffer. (The first project will start at gb).
    // ADD CURRENT PROJECT TO GATHER_BUFFER
    memcpy(gb+offset, coeffs,QoA_project); 


    The COPY GATHER_BUFFER INTO FLASH copies all what have been copied in the gather_buffer in the flash memory. To do so, it copy the offset+QoA_project starting at gb to the beginning of FLASH_USER (The first project will start at FLASH_USER).
    // COPY GATHER_BUFFER INTO FLASH
    memcpy(FLASH_USER, gb, offset+QoA_project);



    I execute these 3 functions in a thread named "SaveJob.C". The header of this thread is the following :

            persist.UserData[0]=1; //Save project number 1
    int project = persist.UserData[0]; //Put the project number in persist Data
    int QoA_project = (ParametricIndex+1)*sizeof(ParametricCoeffs[0]); //Quantity of bytes to save.
    persist.UserData[project] = QoA_project; // Keep track of the number of bytes of this project.
    int offset = get_offset(); // Bytes of every previously saved project 
    char * gb = (char *)gather_buffer;  // Pointer of 1 bytes starting at beginning of gather_buffer
            char * coeffs = (char *) ParametricCoeffs; // Pointer of 1 bytes starting at beginning of ParametricCoeffs

    Where the get_offset(); function is the following (It works fine, I tested it) :

    int get_offset()
    {
    int offset = 0;
    int p;
    if (persist.UserData[0]==1)     //persist.UserData[0] contains the project number
    offset=0;
    else {
    for (p = (persist.UserData[0])-1;p>0;p--)
    {
    offset += persist.UserData[p];  // persist.UserData[p] contains the QoA_project (number of bytes) of                                                                      //  the project.
    }
    }
    return offset;
    }


    Finally, I use another thread (LoadJob.C) that contains the following function :

            //COPY SPECIFIC PROJECT'S BYTES FROM FLASH TO COORD MOTION BUFFER
    memcpy(coeffs,FLASH_USER+offset,QoA_project);

    This function copy QoA_project  bytes (which is the number of bytes needed by the selected project) from FLASH_USER+offset (where the project is supposed to be in the flash memory) to the beginning of the Coord Motion Buffer.

    When I execute these threads, ( I save 2 different project and then I load the first one), and then I execute the CoordMotionBuffer:  LastCoordSystem0=&ParametricCoeffs[0];
    ExecBuf();

    which should contain the project 1 because of memcpy(coeffs,FLASH_USER+offset,QoA_project); , The offset and QoA_project are good in the persist data but the real number of bytes in the CoordMotionBuffer:(ParametricIndex+1)*sizeof(ParametricCoeffs[0]); 

    is still the same as the last executed job (project 2) and it do not even execute... I changed the persist.UserData[0] (contains the number of the project between each saving process to be sure to not overwrite on previous project.

    I'm sorry for the long message I wanted to detail more then less, I really need it to work. ( I attached my C files)

    Thanks for your support,

    Guillaume























    On Wednesday, July 13, 2016 5:07 PM, "Hardy Family hardy.woodland.cypress@... [DynoMotion]" <DynoMotion@yahoogroups.com> wrote:


     
    You seem to be misunderstanding the concept of pointer arithmetic.  If "offset" is a number of bytes, then "gather_buffer+offset" is not doing what you expect.  This is because gather_buffer is a pointer to double (i.e. units of 8 bytes) and the compiler will then treat "offset" as a number of doubles, rather than a number of bytes.

    The code you wrote would copy all projects (except for the first) to the wrong location in the gather buffer.  (8 times too far away).

    To avoid confusion, create some temporary variables which are pointers to byte (or char).  So don't use gather_buffer directly, but (like Tom showed before):

    char * gb = (char *)gather_buffer;

    and change
    memcpy(gather_buffer+offset, &ParametricCoeffs[0], QoA_project);
    to
    memcpy(gb+offset, &ParametricCoeffs[0], QoA_project);

    Regards,
    SJH

    On Wed, Jul 13, 2016 at 12:50 PM, gyelle10@... [DynoMotion] <DynoMotion@yahoogroups.com> wrote:
     
    Hello SJH and Tom,

    I tried an other approach with your advices, I think I'm close but it still doesn't work. I use memcpy(..) to copy memory at each step :

    When I want to save a project, I do the following :
    (Note that offset is the quantity of bytes of every projects before the selected one, and QoA_object is the quantity of Bytes of the selected project)

    //COPY FLASH IN GATHER

    memcpy(gather_buffer, FLASH_USER, offset); 
    //copy memory (offset Bytes) from FLASH_USER to gather_buffer;
    // ADD CURRENT PROJECT (in CoordMotionBuffer) TO GATHER_BUFFER
    memcpy(gather_buffer+offset, &ParametricCoeffs[0], QoA_project);
     //copy memory (QoA_project Bytes) from beginning of CoordMotionBuffer to gather_buffer (after previously saved projects)
    // COPY ALL GATHER_BUFFER INTO FLASH
    memcpy(FLASH_USER, gather_buffer, offset+QoA_project);
     //Copy all the Bytes (offset+QoA_project) from gather_buffer to FLASH_USER



    And then to load a specific project I do :

    //COPY THE SPECIFIC PROJECT'S BYTES FROM FLASH TO COORD MOTION BUFFER
    memcpy(&ParametricCoeffs[0], FLASH_USER+offset, QoA_project);


    Finally, I execute the CoordMotionBuffer with :

                                    LastCoordSystem0=&ParametricCoeffs[0];
    ExecBuf();

    When I execute, the number of bytes in the CoordMotionBuffer remains the same as the last job i've done and it doesn't start. It is hard to see whats wrong because I don't know which step is wrong..

    Do you have an idea of whats wrong ?

    Thanks in advance,

    Guillaume


    On Wednesday, July 13, 2016 1:38 AM, "Hardy Family hardy.woodland.cypress@... [DynoMotion]" <DynoMotion@yahoogroups.com> wrote:


     
    Check out the bottom of
    http://dynomotion.com/Support.html
    for a list of resources for help programming C.

    Note that the memcpy() function is available (even though it may not be listed in KMotionDef.h).  memcpy() copies bytes from one location to another, without regard for the type of pointed-to objects.  For example:

    extern void * memcpy(void * dest, const void * source, unsigned int number_of_bytes);  // external definition

    (in C, void* means "pointer to an unspecified object" so you can use any pointer as a parameter in this case.)

    Then, if you want to copy from flash to the gather buffer:

    memcpy(gather_buffer, FLASH_USER, sizeof(PARAMETRIC_COEFF) * number_of_parametric_coeffs);

    where as you can see, you calculate the number of bytes to copy by using sizeof() multiplied by the number of items of that type to copy.

    Take care when using memcpy that the destination is big enough to contain the source data, since the compiler cannot check this for you.  In this case, the gather buffer is much bigger than the flash chip, so this is not a problem.  But always exercise caution.

    Regards,
    SJH


    On Tue, Jul 12, 2016 at 7:06 PM, Tom Kerekes tk@... [DynoMotion] <DynoMotion@yahoogroups.com> wrote:
     
    Hi Guillaume,
    Please read up about C Pointers.  You are missing some

    (Message over 64 KB, truncated)
    Group: DynoMotion Message: 13580 From: Tom Kerekes Date: 7/14/2016
    Subject: Re: Writing 2nd half flash

    Hi Guillaume,

    SJH's routine looks perfect

    I just wanted to answer your question the Flash Chip Erase block sizes are 64KBytes.  The Flash chip Address Banking is in 16KByte address ranges.

    Regards

    TK


    On 7/14/2016 1:03 PM, Hardy Family hardy.woodland.cypress@... [DynoMotion] wrote:
     
    You need to call SetFlashBank with the address you are going to access, your code is always using the same address each time (in first loop) and ignoring the offset in the second loop.

    How about you write a function which copies any amount of data from flash to other memory.  Something like this:

    void memcpy_from_user_flash(void * dest, int byte_offset_in_user_flash, int num_bytes)
    {
      const char * f = (const char *)FLASH_USER + byte_offset_in_user_flash;
      char * m = (char *)dest;

      while (num_bytes > 0) {
        SetFlashBank(f);
        *m++ = *f++;
        --num_bytes;
      }
    }

    This is simple and inefficient, but "premature optimization is the root of all evil"...

    Regards,
    SJH


    On Thu, Jul 14, 2016 at 12:24 PM, gyelle10@... [DynoMotion] <DynoMotion@yahoogroups.com> wrote:
     
    Hi Tom,

    I allready had changed for the ProgramFlash function to write data :) 

    You wrote that Flash chip is banked in 16KByte banks, is this an error ? isn't it 64KByte ? Anyway, the Flash Bank is not clear to me. It sets the currentrly addressable flash bank, so to update the Flash bank every byte I write SetFlashBank(FLASH_USER+1 byte) at each byte ? Here is my for loop to copy flash in gather_buffer or in CoordMotionBuffer :

    char * gb = (char *)gather_buffer;  // Pointer of 1 bytes starting at beginning of gather_buffer
    char * coeffs = (char *) ParametricCoeffs; // Pointer of 1 bytes starting at beginning of ParametricCoeffs
    char *p=(char *)FLASH_USER;  // pointer to the User FLASH Chip area.

    for (i=0; i<=offset; i++)
    {
    SetFlashBank(FLASH_USER+1);
    gb[i]=p[i];
    }
    And to copy from flash to coord Motion Buffer :

    for (i=0; i<=QoA_project; i++)
    {
    SetFlashBank(FLASH_USER+i);
    coeffs[i]=p[i+offset];
    }

    It works fine for but only for first ~16Kbytes so I guess you were right about 16Kbytes ! I also guess that my SetFlashBank is not set properly.. 

    Thanks in advance,

    Guillaume

     


    On Thursday, July 14, 2016 1:10 PM, "Tom Kerekes tk@... [DynoMotion]" <DynoMotion@yahoogroups.com> wrote:


     
    Hi Guillaume,
    It seems your SaveJob.c program is trying to memcpy the data to the Flash Chip.  The Flash is read only memory and is also memory banked.  Use The ProgramFlash function to write data to the Flash chip.
    Another problem is that the Flash chip is banked in 16KByte banks.  memcpy does not know this.  It will not set the bank and update the bank when it crosses 16KByte boundaries.  You will need to do this.  The simplest thing would be to just use a for loop to move the memory one byte at a time and update the Flash bank every byte.  That may be slow.  Once you get it working correctly you can optimize it to do memcpy bursts of 16KBytes.
    There may be some variables that need to be properly set for each project.  Such as:
    extern double CS0_TimeDownloaded;    // Sum of all Coord Motion Segments downloaded from Host
    extern double CS0_TimeLost;            // Sum of all Coord Motion Segments downloaded from Host that have been discarded (buffer wrap)
    Those are all I can think of.  CS0_TimeLost should aways be set to zero because all your data is assumed to be less than one full buffer.
    The length of the data isn't required because there is a termination segment at the end.
    HTH
    Regards
    TK



    On 7/14/2016 8:14 AM, gyelle10@... [DynoMotion] wrote:
     
    You are right, my base in C are not very strong.. at least I understand what you are saying and I read on pointer.

    I tried it but it still not work.. What does the memcpy() function do exactly ?  How I see it is for the first function (COPY FLASH IN GATHER), memcpy() takes the first "offset" bytes starting at FLASH_USER. and copy starting at beginning  of gb (gather_buffer). Because FLASH_USER and gb point to 1 byte memory case, each copied bytes follow each others by 1 adress.
    //COPY FLASH IN GATHER
    memcpy(gb, FLASH_USER, offset); 

            
    The  ADD CURRENT PROJECT TO GATHER_BUFFER function does the same but copy exacly what is currently in the CoordMotionBuffe (QoA_project bytes, which include the terminated segment) byte per byte. Even if ParametricCoeffs points to 216 bytes arguments, it will copy 1 byte at a time because the pointer is char * coeffs. It will copy theses bytes to gb+offset, which means after the previously copied bytes in the gather_buffer. (The first project will start at gb).
    // ADD CURRENT PROJECT TO GATHER_BUFFER
    memcpy(gb+offset, coeffs,QoA_project); 


    The COPY GATHER_BUFFER INTO FLASH copies all what have been copied in the gather_buffer in the flash memory. To do so, it copy the offset+QoA_project starting at gb to the beginning of FLASH_USER (The first project will start at FLASH_USER).
    // COPY GATHER_BUFFER INTO FLASH
    memcpy(FLASH_USER, gb, offset+QoA_project);



    I execute these 3 functions in a thread named "SaveJob.C". The header of this thread is the following :

            persist.UserData[0]=1; //Save project number 1
    int project = persist.UserData[0]; //Put the project number in persist Data
    int QoA_project = (ParametricIndex+1)*sizeof(ParametricCoeffs[0]); //Quantity of bytes to save.
    persist.UserData[project] = QoA_project; // Keep track of the number of bytes of this project.
    int offset = get_offset(); // Bytes of every previously saved project 
    char * gb = (char *)gather_buffer;  // Pointer of 1 bytes starting at beginning of gather_buffer
            char * coeffs = (char *) ParametricCoeffs; // Pointer of 1 bytes starting at beginning of ParametricCoeffs

    Where the get_offset(); function is the following (It works fine, I tested it) :

    int get_offset()
    {
    int offset = 0;
    int p;
    if (persist.UserData[0]==1)     //persist.UserData[0] contains the project number
    offset=0;
    else {
    for (p = (persist.UserData[0])-1;p>0;p--)
    {
    offset += persist.UserData[p];  // persist.UserData[p] contains the QoA_project (number of bytes) of                                                                      //  the project.
    }
    }
    return offset;
    }


    Finally, I use another thread (LoadJob.C) that contains the following function :

            //COPY SPECIFIC PROJECT'S BYTES FROM FLASH TO COORD MOTION BUFFER
    memcpy(coeffs,FLASH_USER+offset,QoA_project);

    This function copy QoA_project  bytes (which is the number of bytes needed by the selected project) from FLASH_USER+offset (where the project is supposed to be in the flash memory) to the beginning of the Coord Motion Buffer.

    When I execute these threads, ( I save 2 different project and then I load the first one), and then I execute the CoordMotionBuffer:  LastCoordSystem0=&ParametricCoeffs[0];
    ExecBuf();

    which should contain the project 1 because of memcpy(coeffs,FLASH

    (Message over 64 KB, truncated)